package licode.unisop.realm.domainx.model;

import licode.unisop.realm.domainx.dp.Name;
import licode.unisop.realm.domainx.dp.NickName;
import licode.unisop.realm.domainx.exception.UserStateException;
import licode.unisop.types.dp.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 定义用户的实体，实体的唯一标识位userId
 */
@Getter
public class UserInfo {

    /**
     * 用户标识
     */
    private String userId;
    private String password;

    /**
     * 用户头像
     */
    private String avatar;

    /**
     * 用户签名
     */
    private String signature;

    /**
     * 身份证号码
     */
    private String idCard;

    /**
     * 身份证附件信息
     */
    private String idInfo;

    /**
     * 用户名称
     */
    private String name;

    /**
     * 用户别名
     */
    private String nickName;

    private String mobile;

    @Setter
    private String salt;
    /**
     * 性别（男、女）
     */
    private String gender;

    /**
     * 用户状态（0：正常；1：停用；2：删除）
     */
    private int state;

    /**
     * 用户账号信息
     */
    private List<AccountVo> accounts;
    private List<AuthInfoVo> authInfos;

    @Setter
    private String userAuth;
    @Setter
    private String userProps;
    @Setter
    private String userUrls;
    @Setter
    private String userExt;

    /**
     * 用户创建时间
     */
    @Setter
    private LocalDateTime createTime;
    @Setter
    private LocalDateTime updateTime;

    @Setter
    private LocalDateTime lastLoginTime;

    public static UserInfo createUser() {
        UserInfo userInfo = new UserInfo();

        userInfo.avatar = "";
        userInfo.signature = "这家伙很懒，什么都没留下！";
        userInfo.userId = "";
        userInfo.createTime = LocalDateTime.now();
        userInfo.name = Name.EMPTY.getName();
        userInfo.nickName = NickName.EMPTY.getNickName();
        userInfo.gender = Gender.MALE.toString();
        userInfo.mobile = Mobile.EMPTY.getMobile();
        userInfo.state = UserState.NO_ACTIVATE.getState();
        userInfo.salt = "";
        userInfo.accounts = new ArrayList<>();
        userInfo.password = "";

        return userInfo;
    }

    public String getId() {
        return userId;
    }

    public boolean checkPassword(String password) {
        return this.password.equals(password);
    }

    public void changeGender(Gender gender) {
        this.gender = gender.toString();
    }

    public void changeMobile(Mobile mobile) {
        this.mobile = mobile.getMobile();
    }

    public void changeSalt(String salt) {
        this.salt = salt;
    }

    public void changeAvatar(String avatar) {
        this.avatar = avatar;
    }

    public void changeSignature(String signature) {
        this.signature = signature;
    }

    public void changeGender(String gender) {
        this.gender = Gender.build(gender).toString();
    }

    public void updateLastLoginTime() {
        this.lastLoginTime = LocalDateTime.now();
    }

    public void changeUserId(UserId userId) {
        this.userId = userId.getId();
    }

    public void changeState(UserState state) {
        this.state = state.getState();
    }

    public void changeIdCard(IdCard idCard) {
        this.idCard = idCard.getId();
    }

    public void changeIdInfo(String idInfo) {
        this.idInfo = idInfo == null ? "" : idInfo;
    }

    public void changePassword(Password password) {
        this.password = password.getPassword();
    }

    public void activateUser() throws UserStateException {
        if (state != UserState.NO_ACTIVATE.getState()) {
            throw new UserStateException("state should equal 0, current " + getState());
        }
        state = UserState.ACTIVATED.getState();
    }

    public void setAccountVos(List<AccountVo> accountVos) {
        this.accounts = new ArrayList<>(accountVos);
    }

    public void setAuthInfo(List<AuthInfoVo> authInfos) {
        this.authInfos = new ArrayList<>(authInfos);
    }

    public void stopUse() throws UserStateException {
        if (state != UserState.ACTIVATED.getState()) {
            throw new UserStateException("state should equal 0, current " + getState());
        }
        state = UserState.STOPPED.getState();
    }

    public void reuse() throws UserStateException {
        if (state == UserState.STOPPED.getState()) {
            state = UserState.ACTIVATED.getState();
        } else {
            throw new UserStateException("state should equal 1, current " + getState());
        }
    }

    public void removeUser() {
        state = UserState.DELETED.getState();
    }

    public boolean isActivated() {
        return this.state == UserState.ACTIVATED.getState();
    }

    public boolean isStopped() {
        return this.state == UserState.STOPPED.getState();
    }

    public boolean isDeleted() {
        return this.state == UserState.DELETED.getState();
    }

    public void changeName(Name name) {
        this.name = name.getName();
    }

    public void changeNickName(NickName nickName) {
        this.nickName = nickName.getNickName();
    }

    public void changeLastLoginTime(LocalDateTime lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "userId=" + userId +
                ", password=" + password +
                ", idCard=" + idCard +
                ", idInfo='" + idInfo + '\'' +
                ", name=" + name +
                ", nickName=" + nickName +
                ", mobile=" + mobile +
                ", salt='" + salt + '\'' +
                ", gender=" + gender +
                ", state=" + state +
                ", accountInfo=" + accounts +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                ", lastLoginTime=" + lastLoginTime +
                '}';
    }
}
